﻿
#pragma once
#include "Engine/common.h"
#include "DNF定义.h"

//对于主动技能，调用者通过 获取伤害() 和 获取冷却() 来获取数据
//[数据表]之外的其他字段都无需转换，直接访问即可
//不设[TP等级]和[应用护石]时，返回原始数据
//[应用护石]使用带满符文的属性，不支持少带符文的情况
//符文加成固定，交给职业类处理
//带条件的情况，如队友数，敌人数，柔化等，交给职业类处理，特殊情况可访问角色对象的设置
//忽略对某一段有影响的情况，直接选取合适的情况，比如回天璇鸣剑段数；忽略固定减冷却的情况

//对于被动技能，调用者通过 应用被动技能() 将属性加到[角色对象]中
//很多字段没有意义，直接忽略，不要访问无效的字段
//带条件的情况，如单刷，CP武器，武器精通等，在[角色对象]中有相关字段，直接判断
class DNF技能对象
{
public:
	int 索引;	//索引为-1时代表无效对象
	WCHAR* 名称;	//静态数据
	int 所属职业;
	int 技能类型;	//注意四种类型是互斥的
	BOOL 可用护石;
	BOOL 可用符文;
	BOOL 可用TP;

	int 学习等级;
	int 等级上限;
	int 精通等级;
	int 版本等级;	//人物满级时，能手动加到的最高等级
	int TP学习等级;
	int TP等级上限;
	int TP精通等级;

	int 无色数量;
	float 手搓冷却缩减;
	float 冷却时间;
	//float 护石冷却减少率;	//不设置此数据，直接在 获取冷却() 计算
	//float 护石伤害增加率;	//不设置此数据，有些护石会改变形态，在[数据表]多准备几份数据
	//float TP伤害增加率;	//不设置此数据，直接在 获取伤害() 计算
	int 数据表数量;
	//表的数量为[数据表数量]，每个表的项数为[等级上限]，表预留10个槽位，项预留100个槽位
	//可能多段伤害放在多个表中，计算时求和返回，也可能在Excel中合并成一个表，直接返回
	//也可能是被动数据，每项代表不同属性，应用给角色对象
	//要求每个表都是写在程序内的静态数据，不加载动态数据
	//注意0级数据为0，正式数据索引从1开始
	float* 数据表[10];

	//int 特殊条件;	//位组合，废弃，直接访问角色对象获取条件
	int ResId;		//护石图标和技能图标一样
	int 符文起始ResId;	//5个符文图标的ResId定义连续
	BOOL 白金徽章可选;
	BOOL 时装上衣可选;

	//int SP消耗;
	//int TP消耗;
	//int MP消耗;	//每级都不一样
	//float 施放时间;	//与速度有关，需要逐帧分析
	//float 手搓MP缩减;
	//BOOL 是否转职技能;
	//BOOL 是否转职可学技能;

	DNF技能对象()
	{
		索引=-1;
		名称=NULL;
		所属职业=-1;
		技能类型=0;
		可用护石=FALSE;
		可用符文=FALSE;
		可用TP=FALSE;

		学习等级=999;
		等级上限=0;
		精通等级=0;
		版本等级=0;
		TP学习等级=999;
		TP等级上限=0;
		TP精通等级=0;
		无色数量=-1;
		手搓冷却缩减=0.0f;
		冷却时间=0.0f;

		数据表数量=0;
		for (int i=0;i<10;i++)
			数据表[i]=NULL;
		
		ResId=-1;
		符文起始ResId=-1;
		白金徽章可选=FALSE;
		时装上衣可选=FALSE;
	}

	virtual ~DNF技能对象()
	{

	}

	virtual void 初始化()=0;

	//符文加成固定，交给职业类处理
	virtual float 获取伤害(int 等级,int TP等级=0,BOOL 应用护石=FALSE)
	{
		return 0.0f;
	}

	//符文加成固定，交给职业类处理；TP似乎不会影响冷却
	virtual float 获取冷却(BOOL 应用护石=FALSE)
	{
		return 0.0f;
	}

	virtual void 应用被动技能(int 等级)
	{

	}
};

struct 技能符文数量组合
{
	BYTE 红色数量;
	BYTE 蓝色数量;
	BYTE 紫色数量;
	BYTE 绿色数量;
};

//职业对象为全部技能提供50个槽位
//技能对象为每个技能的等级提供101个槽位
//（槽位含0级，基础精通200级需要201个槽位暂不考虑）
//职业对象全部使用静态内存，不需要释放
static const int 技能数量上限=50;
static const int 技能等级上限=101;

extern float 防具精通_品质常数[品质总数];
extern float 防具精通_部位比例[5];

class DNF职业对象
{
public:
	//固定信息
	int 职业;
	DNF攻击类型 攻击类型;
	BOOL 是否固伤;
	BOOL 是否辅助;
	int 技能总数量;
	int 主动技能数量;
	int 被动技能数量;
	int 被动技能索引;	//=主动技能数量
	DNF技能对象* 职业技能列表[技能数量上限];	//主动技能在前，被动技能在后，理论上与定义顺序一致
	int Buff图标ResId;

	//动态属性
	int 技能等级增加量[技能数量上限];
	float 技能攻击力增加量[技能数量上限];	//按等级提升技攻是加算，描述为[技能攻击力]，与其他技攻乘算
	float 技能冷却剩余量[技能数量上限];
	float 技能恢复加快量[技能数量上限];
	int 技能无色数量[技能数量上限];		//设置条件时，直接访问此字段
	float 技能无色攻击力增加量[技能数量上限];	//无色伤害是加算，描述为[技能攻击力]，与其他技攻乘算，需要先统计无色数量
	float 技能手搓伤害倍率[技能数量上限];	//黎明圣杯，高科技闪影项链，恩特护肩，红皮武器，均为乘算
	float 技能手搓冷却倍率[技能数量上限];	//高科技战术强化靴，恩特护肩，红皮武器，加算
	float 技能冷却削减量;		//加算冷却
	
	//float 技能范围[技能数量上限];	//乘算，与计算无关，不记录

	//设置数据方法
	void 重置属性();
	void 技能等级增加(WCHAR* 技能名,int 等级数);
	void 技能等级增加(int 起始等级,int 结束等级,int 等级数,int 技能类型过滤);	//指定全部技能范围填1~100，所有方法都是
	void 技能攻击力增加(int 起始等级,int 结束等级,float 增加量,int 技能类型过滤=主动全部技能);
	void 技能冷却减少(int 起始等级,int 结束等级,float 减少量,int 技能类型过滤=主动全部技能);		//减少为正，增加为负
	void 技能恢复加快(int 起始等级,int 结束等级,float 加快量,int 技能类型过滤=主动全部技能);
	void 技能冷却削减(float 技能冷却削减量);
	//[无色数量]为0时，代表不消耗无色的技能，其余情况均表示等于此无色量的技能，上限17个，负数无意义
	void 技能无色攻击力增加(int 起始等级,int 结束等级,int 增加量,int 无色数量);
	void 技能无色冷却减少(int 减少量,int 无色数量);	//只有无色耳环用到，范围固定为1~100非觉醒技能
	void 技能手搓伤害倍率提升(float 提升率,int 技能类型过滤);
	void 技能手搓冷却倍率增加(float 提升量,BOOL 无色限制);
	void 全部TP技能等级增加(int 等级数);	//直接作用于[当前角色对象->技能TP等级]，没重置不能再算第二遍

	//有默认实现的接口
	virtual int 计算技能等级(int 技能索引);
	virtual double 计算技能单次基础伤害(int 技能索引);
	virtual float 计算技能单次基础冷却(int 技能索引);
	virtual void 应用被动技能(int 技能索引);			//内部会判断技能等级是否为0，决定是否应用
	virtual double 计算技能总伤害(int 技能索引);		//由[计算核心]判断次数是否为0，以及是否被动技能，调用此函数不做额外判断直接计算
	virtual double 计算技能最终冷却(int 技能索引);	//由[计算核心]判断次数是否为0，以及是否被动技能，调用此函数不做额外判断直接计算
	virtual void 获取系统奶排除属性值(int* 力量排除结果,int* 智力排除结果);

	//子类必须实现的接口
	virtual void 初始化()=0;
	virtual void 应用职业基本属性()=0;
	virtual double 职业技能伤害调整(int 技能索引,double 单次基础伤害)=0;
	virtual float 职业技能冷却调整(int 技能索引,float 单次基础冷却)=0;
	virtual void 应用职业防具精通属性()=0;

	//和计算关系不大的方法
	int 获取白金徽章技能列表(WCHAR** 结果缓冲区);	//缓冲区不小于[技能数量上限]，且不能修改返回的指针
	int 获取装扮上衣技能列表(WCHAR** 结果缓冲区);	//缓冲区不小于[技能数量上限]，且不能修改返回的指针
	int 获取技能索引(WCHAR* 技能名);	//防止插入顺序和定义顺序不一样（可能吗？）

	BOOL 是辅助职业()
	{
		return 是否辅助==TRUE;
	}
};

//所有类型装备的属性都集中在一个类，不再拆分子类
//大部分字段是共用的，类型专属字段以[装备类型]区分，可能不会使用某些共用字段
//受开发时间影响，可能某些应该有的字段也不会填写
//初始化时，将装备按类型放入容器，批量赋予类型
//未定义类型的设置项直接赋予数值，或提供专用函数计算数值，不生成装备对象
class DNF装备对象
{
public:
	DNF装备类型 装备类型;

	//基本属性
	BOOL 空装备;	//无装备也有对象，检查带没带装备不能用NULL

	//由于不提供武器类型的装备对象，以及自定义装备不直接提供描述，UI那边不再使用装备对象获取数据
	//改用几个专门的函数，通过规则返回对应属性，包括图标、名称、描述、品质、部位

	//但是以下几个字段计算时仍可能用到
	int 装备Id;			//装备类必须写，防止忘记这件装备是什么
	DNF装备部位 部位;	//装备类必须写，防止忘记部位
	WCHAR* 名称;		//装备的名称根据[装备Id]到[DNF装备名称]取，词条的名称无用，其余类型必须填写名称，UI添加时会用到
	
	DNF品质 品质;	//重要，装备细分类型为自定义时，以传说品质确定领域之主，防具精通计算时确定等级，攻强成长系数也要用
	DNF装备细分类型 装备细分类型;	//重要，计算核心会根据此字段决定是否使用自定义词条，也会根据此字段确定攻强成长系数
	int 套装索引;	//重要，计算核心依靠此字段计算套装件数

	//int 等级;					//忽略等级，计算公式的等级参数均为105，领域之主105级，其余装备均为升神后的110
	//DNF武器类型 武器类型;		//角色类武器使用单独的动态对象，[装备对象表]中对应项为NULL
	//WCHAR* 装备描述;			//忽略，装备描述保存在文件里，由UI读取和设置，和计算没关系
	//BOOL 条件触发;	//废弃，使用 统计条件() 和 获取条件状态() 确定
	//int 标签;		//废弃，装备的描述性分类，位组合，时间不够
	//DNF自定义系列 装备专属系列;	//原本用于UI过滤词条，现决定提供专门的函数处理，可忽略

	//如有需要的属性，用到时再加，只要保证默认为0或-1无影响即可


	//词条类专用
	WCHAR* 装备描述;		//UI会读取描述文件，处理好装备描述的显示
						//但是没有装备描述时，词条对象的可读性太差，如果需要可以给加上


	//附魔类专用
	int 附魔可用部位;	//DNF附魔可用部位，位组合
	//WCHAR* 名称;		//附魔的名称必须加上部位，否则会重名

	//徽章类专用
	DNF徽章类型 徽章类型;
	int 徽章颜色;	//DNF徽章颜色，位组合
	WCHAR* 白金徽章技能名;

	//宠物装备类专用
	DNF宠物装备颜色 宠物装备颜色;

	DNF装备对象()
	{
		空装备=FALSE;

		装备类型=装备类;
		装备Id=-1;
		名称=NULL;
		品质=史诗;
		部位=(DNF装备部位)-1;
		装备细分类型=固定装备;
		套装索引=-1;
		装备描述=NULL;

		//武器类型=武器_未知;
		//等级=110;
		//条件触发=FALSE;
		//装备专属系列=非自定义系列;
		//词条专属系列=通用系列;
		//词条描述行数=0;

		附魔可用部位=0;

		徽章颜色=0;

		宠物装备颜色=(DNF宠物装备颜色)-1;
	}

	virtual void 初始化()
	{

	}

	virtual void 应用属性()
	{

	}

	//装备、贴膜和词条的伤害属性受各种条件影响，且装备自身也会影响条件
	//需要将装备的条件类属性和非条件类属性分开加入，典型的有各种标记，异常抗性，MP消耗量
	//但是与顺序有关的条件（如无色数）或特殊条件（附魔倍率）由计算核心额外实现
	//非装备类型的对象均无条件限制，或静态条件，不需要实现 统计属性()
	virtual void 统计属性()
	{
	
	}

	//弃用此接口，改用 DNF角色对象::添加条件信息() 主动添加
	//virtual BOOL 获取条件状态(WCHAR* OutBuf)
	//{
	//	if (OutBuf!=NULL)
	//		wcscpy(OutBuf,L"无触发条件");
	//	return TRUE;	//是否满足
	//}

};

class DNF武器对象
{
public:
	BOOL 空装备;
	int 装备索引;
	DNF品质 品质;
	DNF武器类型 武器类型;
	DNF武器系列 武器系列;
	BOOL 雾神武器;
	float 攻强成长倍率;

	void 统计属性();
	void 应用属性();
	void 应用基础属性();

private:
	void 应用雾神武器属性();
	void 统计雾神武器属性();
};

class DNF装扮对象
{
public:
	int 装扮部位品质[装扮部位总数];
	int 装扮属性索引[装扮部位总数];
	WCHAR 上衣技能[100];

	void 设置装扮参数(DNF装扮部位 部位,int 品质索引,int 属性索引);	//与设置模块相关
	void 设置上衣技能(WCHAR* 上衣技能);
	void 应用属性();
};

class DNF辟邪玉对象
{
public:
	int 辟邪玉词条索引[4];
	float 辟邪玉词条数值[4];

	void 设置辟邪玉参数(int 编号,int 词条索引,float 词条数值);	//与设置模块相关
	void 应用属性();
	void 计算辟邪玉属强加成(int* 火强结果,int* 冰强结果,int* 光强结果,int* 暗强结果);
};


//角色类集成了设置、属性、条件状态
//另一半属性在职业类里，两者共同提供修改属性的接口
class DNF角色对象
{
public:
	//当前装备和设置
	DNF装备对象* 角色装备[全部装备部位总数];	//武器为空，使用动态构造的武器对象；武器贴膜也为空
	DNF武器对象* 武器动态对象;
	BOOL 使用武器贴膜;	//武器贴膜就2个选项，也没有其他属性，只需要一个标记就够了

	int 装备强化类型[装备含武器部位总数];
	int 装备强化等级[装备含武器部位总数];
	int 武器锻造等级;

	DNF装备对象* 角色附魔[拓展装备部位总数];
	DNF装备对象* 角色徽章1[装备部位总数];	//没有耳环
	DNF装备对象* 角色徽章2[装备部位总数];	//没有左右槽和耳环

	DNF装备对象* 角色装备词条1[装备含武器部位总数];
	DNF装备对象* 角色装备词条2[装备含武器部位总数];
	DNF装备对象* 角色装备词条3[装备含武器部位总数];
	DNF装备对象* 角色装备词条4[装备含武器部位总数];

	DNF装备对象* 武器融合词条[3];
	DNF装备对象* 传说融合词条[9];
	//DNF装备对象* 右槽融合词条[3];
	//DNF装备对象* 耳环融合词条[3];

	BOOL 贴膜升级[6];

	int 武器星团等级;
	int 武器梦境等级;
	int 武器记忆等级;
	int 跨越之忆星团;	//焰_浴火之厄武器系列~雷_镌刻之迹武器系列，不含失衡

	DNF装扮对象* 装扮动态对象;

	DNF装备对象* 武器装扮;
	DNF装备对象* 武器装扮徽章[2];

	DNF装备对象* 皮肤;
	DNF装备对象* 皮肤徽章[2];

	DNF装备对象* 光环;
	DNF装备对象* 光环徽章[2];

	DNF辟邪玉对象* 辟邪玉动态对象;

	int 星辰百变数量;
	int 副武器状态;	//0-无 1-普通史诗 2-雾神20史诗 3-普通太初 4-雾神20太初
	int 副武器强化;
	DNF装备对象* 红色宠物装备;
	DNF装备对象* 蓝色宠物装备;
	DNF装备对象* 绿色宠物装备;
	DNF装备对象* 快捷栏装备;

	DNF品质 勋章品质;
	int 勋章强化;
	DNF品质 守护珠品质[4];

	int 冒险团等级;
	float 公会属性四维;
	float 公会训练官四维;
	float 公会训练官三攻;
	float 公会训练官三速;

	float 结婚属强;
	float 结婚物攻;
	float 结婚魔攻;
	float 结婚独立;
	float 结婚力智;
	float 结婚攻速;
	float 结婚施放;
	float 结婚移速;

	float 晶体契约三攻;
	float 名称装饰卡四维;
	float 名称装饰卡三速;

	float 收集箱三攻;
	float 收集箱四维;
	float 收集箱属强;

	BOOL 适用辅助补正;	//仅适用力智和三攻
	float 四维补正;	//合并辅助属性
	float 三攻补正;	//合并辅助属性
	float 技攻补正;	//合并辅助属性
	float 攻击强化补正;
	float 攻击强化增幅补正;
	float 属强补正[4];
	float 属抗补正[4];
	float 异抗补正[13];
	float 攻速补正;
	float 技能范围补正;
	float MP消耗量补正;

	int 特性类型;
	int 特性等级[14];

	//技能相关的设置（另一半属性在职业类内）
	int 技能等级[技能数量上限];
	int 技能TP等级[技能数量上限];
	int 技能次数[技能数量上限];
	int 技能受宠物加成次数[技能数量上限];	//需限制次数不能超过[技能次数]
	int 技能受手搓加成次数[技能数量上限];	//需限制次数不能超过[技能次数]
	int 技能手搓方向键数量[技能数量上限];	//黎明圣杯专用
	int 技能快捷栏空位;	//14-x
	int 技能在快捷栏里[技能数量上限];		//高科技闪影项链专用
	BOOL 技能使用护石[技能数量上限];
	技能符文数量组合 技能符文数量[技能数量上限];
	float 职业BUFF提升;
	int 职业特殊设置[2];

	DNF场景 场景;	//0-修炼场 1-巴卡尔 2-雾神
	DNF怪物 怪物;	//0-沙袋 1-挑战沙袋 2-巴卡尔 3-雾神
	BOOL 使用药剂[DNF药剂总数];	//DNF药剂

	float 出血触发频率间隔;
	float 中毒触发频率间隔;
	float 灼伤触发频率间隔;
	float 感电触发频率间隔;
	int 出血层数;
	int 中毒层数;
	int 感电层数;
	BOOL 适用控制型异常;
	float 控制型异常触发频率间隔;	//主要是为了冰冻

	float HP范围;
	float MP范围;

	int 队员数量;	//重要，影响单刷属性
	int 怪物数量;

	BOOL 怪物种族标记[怪物种族总数];
	BOOL 敌人状态标记[敌人状态总数];

	BOOL 自身异常状态标记[异常状态总数];
	BOOL 敌人异常状态标记[异常状态总数];



	//角色基本属性
	//只提供增加方法，设置值基于重置操作
	//为避免混乱，初始化时，所有加算属性均不含基础的1，乘算属性均含基础的1；所有提升类接口的参数均不含基础值1
	//特殊情况需要在这里补充说明
	//如有特殊需求，可直接访问相关字段，但是要自行处理好条件影响
	enum DNF角色属性索引
	{
		//固定类属性
		角色物理攻击力,
		角色魔法攻击力,
		角色独立攻击力,
		角色力量,
		角色智力,
		角色体力,	//不统计
		角色精神,	//不统计
		角色物理暴击率,	//统计但不使用
		角色魔法暴击率,	//统计但不使用
		角色攻击速度,
		角色施放速度,
		角色移动速度,
		角色火属性强化,
		角色冰属性强化,
		角色光属性强化,
		角色暗属性强化,
		角色火属性抗性,
		角色冰属性抗性,
		角色光属性抗性,
		角色暗属性抗性,
		角色出血抗性,
		角色中毒抗性,
		角色灼伤抗性,
		角色感电抗性,
		角色冰冻抗性,
		角色减速抗性,
		角色眩晕抗性,
		角色诅咒抗性,
		角色失明抗性,
		角色石化抗性,
		角色睡眠抗性,
		角色混乱抗性,
		角色束缚抗性,
		//百分比类属性
		角色攻击强化,
		角色攻击强化增幅,
		角色技能伤害,
		角色旧_伤害增加,	//不统计
		角色旧_暴击伤害增加,	//不统计
		角色旧_附加伤害,	//不统计
		角色旧_最终伤害增加,	//不统计
		角色旧_三攻增加,
		角色旧_力智增加,
		角色旧_持续伤害,	//不统计
		角色属性总数,
	};
	float 角色属性[角色属性总数];

	void 物攻增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色物理攻击力]+=v;
	}

	void 魔攻增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色魔法攻击力]+=v;
	}

	void 独立增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色独立攻击力]+=v;
	}

	void 三攻增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色物理攻击力]+=v;
		角色属性[角色魔法攻击力]+=v;
		角色属性[角色独立攻击力]+=v;
	}

	void 力量增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色力量]+=v;
	}

	void 智力增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色智力]+=v;
	}

	void 力智增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色力量]+=v;
		角色属性[角色智力]+=v;
	}

	void 四维增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色力量]+=v;
		角色属性[角色智力]+=v;
		角色属性[角色体力]+=v;
		角色属性[角色精神]+=v;
	}

	void 单四维增加(float v);

	void 物理暴击增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色物理暴击率]+=v;
	}

	void 魔法暴击增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色魔法暴击率]+=v;
	}

	void 暴击增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色物理暴击率]+=v;
		角色属性[角色魔法暴击率]+=v;
	}

	void 攻速增加(float v)
	{
		//这里没有做攻速200上限的判断
		//游戏里有这样一种情况需要说明，攻速从武器开始计算，上限200
		//攻速鞋受上限影响，没法吃满200攻速（没有任何影响）
		v*=附魔倍率;
		角色属性[角色攻击速度]+=v;
		if (攻速鞋部位检查())
			攻速鞋适用攻速+=v;
	}

	void 移速增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色移动速度]+=v;
	}

	void 施放加速(float v)
	{
		v*=附魔倍率;
		角色属性[角色施放速度]+=v;
	}

	void 三速增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色攻击速度]+=v;
		角色属性[角色施放速度]+=v;
		角色属性[角色移动速度]+=v;
		if (攻速鞋部位检查())
			攻速鞋适用攻速+=v;
	}

	void 火强增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色火属性强化]+=v;
	}

	void 冰强增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色冰属性强化]+=v;
	}

	void 光强增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色光属性强化]+=v;
	}

	void 暗强增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色暗属性强化]+=v;
	}

	void 全属强增加(float v)
	{
		v*=附魔倍率;
		角色属性[角色火属性强化]+=v;
		角色属性[角色冰属性强化]+=v;
		角色属性[角色光属性强化]+=v;
		角色属性[角色暗属性强化]+=v;
	}

	float 获取最高属强()
	{
		return max(max(角色属性[角色火属性强化],角色属性[角色冰属性强化]),
			max(角色属性[角色光属性强化],角色属性[角色暗属性强化]));
	}

	void 火抗增加(float v)
	{
		//v*=附魔倍率;
		角色属性[角色火属性抗性]+=v;
	}

	void 冰抗增加(float v)
	{
		//v*=附魔倍率;
		角色属性[角色冰属性抗性]+=v;
	}

	void 光抗增加(float v)
	{
		//v*=附魔倍率;
		角色属性[角色光属性抗性]+=v;
	}

	void 暗抗增加(float v)
	{
		//v*=附魔倍率;
		角色属性[角色暗属性抗性]+=v;
	}

	void 全属抗增加(float v)
	{
		//v*=附魔倍率;
		角色属性[角色火属性抗性]+=v;
		角色属性[角色冰属性抗性]+=v;
		角色属性[角色光属性抗性]+=v;
		角色属性[角色暗属性抗性]+=v;
	}

	void 异抗增加(DNF异常状态类型 类型,float v)
	{
		//v*=附魔倍率;
		角色属性[角色出血抗性+(int)类型]+=v;
		if (装备加成开关 && 类型==睡眠)
			装备提供的睡眠抗性+=v;
	}

	void 全异抗增加(float v)
	{
		//v*=附魔倍率;
		角色属性[角色出血抗性]+=v;
		角色属性[角色中毒抗性]+=v;
		角色属性[角色灼伤抗性]+=v;
		角色属性[角色感电抗性]+=v;
		角色属性[角色冰冻抗性]+=v;
		角色属性[角色减速抗性]+=v;
		角色属性[角色眩晕抗性]+=v;
		角色属性[角色诅咒抗性]+=v;
		角色属性[角色失明抗性]+=v;
		角色属性[角色石化抗性]+=v;
		角色属性[角色睡眠抗性]+=v;
		角色属性[角色混乱抗性]+=v;
		角色属性[角色束缚抗性]+=v;
		if (装备加成开关)
			装备提供的睡眠抗性+=v;
	}

	float 获取最高异常状态抗性()
	{
		float v=角色属性[角色出血抗性];
		v=max(v,角色属性[角色中毒抗性]);
		v=max(v,角色属性[角色灼伤抗性]);
		v=max(v,角色属性[角色感电抗性]);
		v=max(v,角色属性[角色冰冻抗性]);
		v=max(v,角色属性[角色减速抗性]);
		v=max(v,角色属性[角色眩晕抗性]);
		v=max(v,角色属性[角色诅咒抗性]);
		v=max(v,角色属性[角色失明抗性]);
		v=max(v,角色属性[角色石化抗性]);
		v=max(v,角色属性[角色睡眠抗性]);
		v=max(v,角色属性[角色混乱抗性]);
		v=max(v,角色属性[角色束缚抗性]);
		return v;
	}

	void 技能伤害提升(float v)
	{
		v*=附魔倍率;	//加算加倍
		角色属性[角色技能伤害]*=1.0+v;
	}

	//有些装备同时具有成长型攻强和固定型攻强，添加默认参数，允许处理特例
	void 攻击强化增加(float v,BOOL 允许成长=TRUE)
	{
		if (允许成长)
			v*=装备攻强成长倍率;
		角色属性[角色攻击强化]+=v;
	}

	void 攻击强化增幅增加(float v)
	{
		角色属性[角色攻击强化增幅]+=v;
	}

	//注意会影响面板
	void 三攻百分比增加(float v)
	{
		角色属性[角色旧_三攻增加]+=v;
	}

	//注意会影响面板
	void 力智百分比增加(float v)
	{
		角色属性[角色旧_力智增加]+=v;
	}


	//角色特殊属性和特殊控制开关
	//一般情况下直接访问字段修改即可，特殊情况会提供Set方法

	float 装备攻强成长倍率;	//不同类型装备适用不同的成长等级，影响攻击强化，应用属性前需要根据装备类型先设置

	float 技能冷却减少记录;
	float 技能恢复加快记录;
	BOOL 面板冷却统计开关;	//大部分属性都计入面板，但是被动的冷却和武器基础冷却不计入，如有需要可用此开关屏蔽
	BOOL 装备加成开关;		//有些属性只希望统计装备数据，不希望被动、特性等干扰，可读取此值

	float 附魔倍率;		//附魔+100%

	WCHAR* 攻速鞋部位标记;	//攻速鞋专用，不是所有部位
	float 攻速鞋适用攻速;	//赛博音速长靴，只有部位标记一致，攻速增加()才同时增加[攻速鞋适用攻速]
	BOOL 攻速鞋部位检查();

	float 装备提供的睡眠抗性;	//永恒的心愿
	float 装备技能范围;	//超界次元，深潜耳环，恩特手镯
	float MP额外消耗量;	//天才技术大师的加厚长靴，蓝灵腰带（仅装备，其他来源的MP消耗不统计）
	BOOL 特性技能增加标记;	//超界次元
	BOOL 酷寒一击标记;	//冰冻打击词条变为无条件增伤
	BOOL 傀儡一击标记;	//石化打击词条变为无条件增伤

	//仅统计装备，且必须是全等级，其他来源的加成不调用
	void 技能范围增加(float v)
	{
		if (装备加成开关)
			装备技能范围+=v;
	}

	//仅统计装备提供的MP消耗量（宠物装备也加），其他来源的加成不调用
	void MP消耗量增加(float v)
	{
		MP额外消耗量+=v;
	}

	float 增伤倍率;		//非技攻的乘算增伤，如斗神药剂和被动
	float 物攻百分比提升率;
	float 魔攻百分比提升率;
	float 独立百分比提升率;	//奶妈被动专用，乘算，影响面板
	float 基础精通倍率;	//全是乘算，仅统计，不计算基础精通

	void 伤害提升(float v)
	{
		增伤倍率*=1.0f+v;
	}

	void 三攻百分比提升(float 物攻提升,float 魔攻提升,float 独立提升)
	{
		物攻百分比提升率*=1.0f+物攻提升;
		魔攻百分比提升率*=1.0f+魔攻提升;
		独立百分比提升率*=1.0f+独立提升;
	}

	void 基础精通伤害提升(float v)
	{
		基础精通倍率*=1.0f+v;
	}

	//异常相关内容
	//其中[触发频率]、[持续时间增加量]、[持续时间百分比增加量]为条件型字段
	struct 异常触发记录 
	{
		//恩特戒指4词条各10%，四种手镯50%，总量不会超过100%（黑灵缠绕，石巨人，流星飞电，生命之力）
		float 伤害占比;
		float 触发频率;
		float 伤害增加量;
		float 持续时间增加量;//加算，持续时间减少不会减少伤害，而是加快结算
		float 持续时间百分比增加量;

		void 重置()
		{
			伤害占比=0;
			触发频率=999;
			伤害增加量=0;
			持续时间增加量=0;
			持续时间百分比增加量=0;
		}

		void 更新频率(float 间隔时间)
		{
			//这里只需要记录最高频率，不考虑破韧与否
			触发频率=min(触发频率,间隔时间);
		}

		void 增加伤害(float 增加量)
		{
			伤害增加量+=增加量;
		}

		void 增加持续时间(float 增加量)
		{
			持续时间增加量+=增加量;
		}

		void 增加持续时间百分比(float 增加量)
		{
			持续时间百分比增加量+=增加量;
		}

		void 增加占比(float 增加量)
		{
			伤害占比+=增加量;
		}
	};
	异常触发记录 异常属性[异常状态总数];
	float 破冰增伤增加量;	//蓝色自然的种子，海湾鞋

	//对"攻击XX异常状态的敌人时，技能伤害+X"词条的特殊处理
	void 异常条件技能伤害提升(DNF异常状态类型 类型,float 提升量);


	WCHAR* 条件记录;
	int 条件记录文字数;
	int 条件数量;
	int 条件满足数量;

	void 添加条件信息(BOOL 满足条件,WCHAR* 描述文本)
	{
		条件数量++;
		条件满足数量+=(满足条件==TRUE);
		if (描述文本!=NULL)
		{
			int Len=wcslen(描述文本);
			wcscpy(条件记录+条件记录文字数,描述文本);
			条件记录文字数+=Len;
			wcscpy(条件记录+条件记录文字数,L"\r\n");
			条件记录文字数+=2;
		}
	}

	//每处理一个部位，就重置一次信息，完成后记录此部位的结果
	void 重置条件信息()
	{
		条件记录文字数=0;
		条件数量=0;
		条件满足数量=0;
	}

	int 套装数量记录[套装总数];
	DNF装备对象* 套装对象[套装总数];
	void 初始化套装对象(int 索引,DNF装备对象* 对象);

	BOOL 部位有装备(DNF装备部位 部位);
	void 重置属性();
	BOOL 穿戴装备检查(WCHAR* 装备名称);	//禁止用于武器
	BOOL 部位穿戴装备检查(int 部位,WCHAR* 装备名称);	//禁止用于武器
	BOOL 穿戴CP武器检查();	//武器对象特殊，不能靠名称检查
	void 初始化();
	void 反初始化();

private:
	void 重置异常();
};


//负责控制流程
//控制顺序和参数，处理特殊情况，保存中间结果，提交最终结果
class DNF计算核心
{
public:
	//[伤害计算结果]里都有对应项，需要在UI展示
	enum 属性索引
	{
		_物理攻击力,	//整数
		_魔法攻击力,	//整数
		_独立攻击力,	//整数
		_力量,		//整数
		_智力,		//整数
		_属性强化占位,
		_攻击强化,
		_攻击强化增幅,
		_技能伤害,
		_直伤占比,
		_冷却减少,
		_技能范围,
		_MP消耗量,
		_攻击速度,
		_施放速度,
		_移动速度,
		_异常伤害占比1,
		_异常伤害占比2,
		_异常伤害占比3,
		_异常伤害占比4,
		_异常伤害增加1,
		_异常伤害增加2,
		_异常伤害增加3,
		_异常伤害增加4,
		_属性抗性占位,
		_异常抗性1,
		_异常抗性2,
		_异常抗性3,
		_异常抗性4,
		_异常抗性5,
		_异常抗性6,
		_异常抗性7,
		_异常抗性8,
		_异常抗性9,
		_异常抗性10,
		_异常抗性11,
		_异常抗性12,
		_异常抗性13,
		_属性强化1,	//整数
		_属性强化2,	//整数
		_属性强化3,	//整数
		_属性强化4,	//整数
		_属性抗性1,	//整数
		_属性抗性2,	//整数
		_属性抗性3,	//整数
		_属性抗性4,	//整数
		属性结果总数,
	};
	float 属性结果[属性结果总数];
	int 系统奶;	//以最高属性计算
	double 总伤害;

	struct 技能结果_t
	{	
		int 技能索引;
		int 技能等级;
		int 技能次数;
		float 技能冷却时间;
		double 技能平均伤害;
		double 技能总伤害;
		float 技能占比;
	};
	int 技能结果数;
	技能结果_t 技能结果[20];

	struct 技能冷却结果_t
	{
		int 技能索引;
		float 技能原始时间;
		float 技能当前时间;
		float 技能缩减率;
		int 技能无色数;
	};
	int 技能冷却结果数;
	技能冷却结果_t 技能冷却结果[20];

	struct 被动技能结果_t 
	{
		int 技能索引;
		float 技能等级;
	};
	int 被动技能数;
	被动技能结果_t 被动技能结果[10];

	struct 装备结果_t
	{
		int 打造物攻加成;	//武器、耳环
		int 打造魔攻加成;	//武器、耳环
		int 打造独立加成;	//耳环
		int 打造四维加成;	//合并同一部位的所有属性（实际只有四维中的一项）
		int 锻造独立加成;	//武器（合并辅助专属加成）
		BOOL 满足条件;
		WCHAR 条件描述[100];
	};
	装备结果_t 装备结果[全部装备部位总数];

	//计算框架相关
	void 初始化();
	void 反初始化();
	void 重置();
	void 执行计算();
	void 生成部位条件触发结果(int 部位);

	//计算功能
	void 应用唤醒属性();
	void 应用勋章属性();
	void 应用结婚属性();
	void 应用名称装饰卡属性();
	void 应用杂项属性();
	void 应用药剂属性();
	void 应用系统奶加成();
	void 应用装备基础属性();
	void 应用特性技能属性();
	void 应用用户补正属性(BOOL 伤害类补正);
	void 主动技能无色数调整();
	void 应用黎明圣杯加成();
	void 应用剑帝副武器加成();
	void 应用星辰百变套装属性();
	void 应用装备强化增幅锻造属性();
	float 获取怪物防御系数(int* 属抗);
	float 异常保有率计算(int 类型);
	void 异常系数计算(float* 异常伤害系数);
};










extern std::vector<DNF技能对象*> 技能对象表;
extern std::vector<DNF职业对象*> 职业对象表;

extern std::vector<DNF装备对象*> 装备对象表[装备类型总数];		//id序
extern std::map<WCHAR*,DNF装备对象*,wstrless_t> 装备对象表_名称[装备类型总数];	//名称序快速查找

//计算时，不再传递参数，直接访问全局变量（只支持单个角色和单个职业）
extern DNF职业对象* 当前职业对象;
extern DNF角色对象* 当前角色对象;
extern DNF计算核心 计算核心;